using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Security.Cryptography;
using System.Data;
using System.Drawing;
using System.Text;
using System.Net;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Xml.Serialization;
using System.Windows.Forms;
using Toenda.Tools.Data;

namespace zapLoader {
	public partial class MainForm : Form {
		ZapprService.ZapprService zs;

		public MainForm() {
			InitializeComponent();

			this.rbPublic.Checked = true;
			this.pbUpload.Minimum = 0;
			this.pbUpload.Value = 0;
			this.pbMarquee.Visible = true;
			this.pbMarquee.Style = ProgressBarStyle.Continuous;

			try {
				zs = new ZapprService.ZapprService();
				string checkOnline = zs.GetName();
			}
			catch(Exception ex) {
				MessageBox.Show(
					"zapLoader needs to be connected to the internet.\n"
					+ ex.Message,
					"zapLoader Error"
				);

				throw new Exception("Application startup error.");
			}
		}

		private void btnUpload_Click(object sender, EventArgs e) {
			bool up = true;

			if(File.Exists(Application.StartupPath + "\\Settings.xml")) {
				//this.pbUpload.Maximum = this.lvMain.Items.Count * 2;
				this.Cursor = Cursors.WaitCursor;

				foreach(ListViewItem lvi in this.lvMain.Items) {
					this.pbUpload.Maximum += Convert.ToInt32(lvi.Tag);
				}

				this.pbUpload.Maximum += this.lvMain.Items.Count;

				foreach(ListViewItem lvi in this.lvMain.Items) {
					if(up) {
						this.pbUpload.Value++;
						this.pbMarquee.Style = ProgressBarStyle.Marquee;

						//MessageBox.Show(
						//    "ImageKey: " + lvi.ImageKey + "\n"
						//    + "Name: " + lvi.Name + "\n"
						//    + "Tag: " + lvi.Tag
						//);

						// create byte buffer for the image
						StreamReader sr = new StreamReader(lvi.ImageKey);

						byte[] byteStream = new byte[sr.BaseStream.Length];
						int i = sr.BaseStream.Read(byteStream, 0, Convert.ToInt32(sr.BaseStream.Length));

						string u = "";
						string p = "";

						try {
							// create crypto byte buffer for the password
							XmlProvider xml = new XmlProvider(
								Application.StartupPath + "\\Settings.xml",
								OpenMode.ForReading
							);

							u = xml.ReadTag("zapLoader", "username");
							p = xml.ReadTag("zapLoader", "password");
						}
						catch(Exception exp) {
							MessageBox.Show(
								exp.Message,
								"zapLoader Error"
							);
							up = false;
						}

						if(up) {
							byte[] byteBuffer = new byte[16];
							MD5CryptoServiceProvider oMD5CSP = new MD5CryptoServiceProvider();
							StreamWriter oSW = new StreamWriter(
								new CryptoStream(Stream.Null, oMD5CSP, CryptoStreamMode.Write)
							);

							oSW.Write(p);
							oSW.Flush();
							oSW.Close();
							byteBuffer = oMD5CSP.Hash;

							try {
								string[] str = this.txtTags.Text.Split(new char[] { ',', ' ' });
								int privacy = (rbPrivate.Checked ? 1 : 0);

								bool ret = zs.UploadPicture(
									u,
									byteBuffer,
									byteStream,
									lvi.Name,
									privacy,
									str
								);

								//MessageBox.Show(ret.ToString());

								this.pbUpload.Value += Convert.ToInt32(lvi.Tag);
							}
							catch(System.Web.Services.Protocols.SoapException sex) {
								MessageBox.Show(
									"ZapprService SOAP Error:\n"
									+ sex.Message,
									"zapLoader Error"
								);

								this.pbMarquee.Style = ProgressBarStyle.Continuous;
								up = false;
							}
							catch(Exception ex) {
								MessageBox.Show(
									"ZapprService APP Error:\n"
									+ ex.Message,
									"zapLoader Error"
								);

								this.pbMarquee.Style = ProgressBarStyle.Continuous;
								up = false;
							}
						}
					}
				}

				if(up) {
					MessageBox.Show("Successfull uploaded", "zapLoader");
					this.lvMain.Items.Clear();
				}

				this.pbMarquee.Style = ProgressBarStyle.Continuous;
				this.pbUpload.Value = 0;
				this.Cursor = Cursors.Default;
			}
		}

		private void exitMenuItem_Click(object sender, EventArgs e) {
			Application.Exit();
		}

		private void infoMenuItem_Click(object sender, EventArgs e) {
			AboutForm af = new AboutForm();

			if(af.ShowDialog() == DialogResult.OK) {
			}
		}

		private void einstellungenToolStripMenuItem_Click(object sender, EventArgs e) {
			SettingsForm sf = new SettingsForm();

			if(sf.ShowDialog() == DialogResult.OK) {
			}
		}

		private void addImageToolStripMenuItem_Click(object sender, EventArgs e) {
			string[] files = this.LoadImageFromDialog();

			if(files != null) {
				ListViewItem lvi;
				FileInfo tmp;
				Bitmap bmp;
				Image thumb;

				foreach(string s in files) {
					try {
						tmp = new FileInfo(s);
						bmp = this.Generate75x75Pixel(new Bitmap(s));

						thumb = bmp.GetThumbnailImage(
							75,
							75,
							new Image.GetThumbnailImageAbort(this.imageAbort),
							IntPtr.Zero
						);

						this.imgList.Images.Add(s, thumb);

						lvi = new ListViewItem();
						lvi.ImageKey = s;
						lvi.Name = tmp.Name;
						lvi.Tag = tmp.Length;
						lvi.Text = tmp.Name;

						if(!this.lvMain.Items.ContainsKey(s)) {
							this.lvMain.Items.Add(lvi);
						}
					}
					catch(IOException ex) {
						MessageBox.Show(ex.Message);
						return;
					}
				}
			}
		}

		private void lvMain_DragEnter(object sender, DragEventArgs e) {
			e.Effect = DragDropEffects.Copy;
		}

		private void lvMain_DragDrop(object sender, DragEventArgs e) {
			if(e.Data.GetDataPresent(DataFormats.FileDrop)) {
				string[] strFileName = (string[])e.Data.GetData(DataFormats.FileDrop);
				ListViewItem lvi;
				Bitmap bmp;
				FileInfo tmp;
				Image thumb;

				for(int i = 0; i < strFileName.Length; i++) {
					try {
						//listBox1.Items.Add((string)"Ext: " + strFileName[i]);

						if(Path.GetExtension(strFileName[i]).ToLower() == ".jpg"
						|| Path.GetExtension(strFileName[i]).ToLower() == ".jpeg"
						|| Path.GetExtension(strFileName[i]).ToLower() == ".gif"
						|| Path.GetExtension(strFileName[i]).ToLower() == ".png"
						|| Path.GetExtension(strFileName[i]).ToLower() == ".bmp"
						|| Path.GetExtension(strFileName[i]).ToLower() == ".tif"
						|| Path.GetExtension(strFileName[i]).ToLower() == ".tiff") {
							tmp = new FileInfo(strFileName[i]);
							bmp = this.Generate75x75Pixel(new Bitmap(strFileName[i]));
							
							thumb = bmp.GetThumbnailImage(
								75,
								75,
								new Image.GetThumbnailImageAbort(this.imageAbort),
								IntPtr.Zero
							);

							this.imgList.Images.Add(strFileName[i], thumb);

							lvi = new ListViewItem();
							lvi.ImageKey = strFileName[i];
							lvi.Name = tmp.Name;
							lvi.Tag = tmp.Length;
							lvi.Text = tmp.Name;
							
							if(!this.lvMain.Items.ContainsKey(strFileName[i])) {
								this.lvMain.Items.Add(lvi);
							}
						}
						else {
							continue;
						}
					}
					catch(IOException ex) {
						MessageBox.Show(ex.Message);
						return;
					}
				}
			}
		}

		// -----------------------------------------
		// PUBLIC PROPERTIES
		// -----------------------------------------

		/// <summary>
		/// Generate a bitmap
		/// </summary>
		/// <param name="image"></param>
		/// <returns></returns>
		public Bitmap Generate75x75Pixel(Bitmap image) {
			if(image == null)
				throw new ArgumentNullException("image");

			Bitmap bmp = null;
			Bitmap crapped = null;
			int x = 0, y = 0;
			double prop = 0;

			if(image.Width > 75) {
				// compute proportation
				prop = (double)image.Width / (double)image.Height;

				if(image.Width > image.Height) {
					x = (int)Math.Round(75 * prop, 0);
					y = 75;
				}
				else {
					x = 75;
					y = (int)Math.Round(75 / prop, 0);
				}

				bmp = new Bitmap((Image)image, new Size(x, y));

				crapped = new Bitmap(75, 75);
				Graphics g = Graphics.FromImage(crapped);
				g.DrawImage(bmp,
				new Rectangle(0, 0, 75, 75),
				new Rectangle(0, 0, 75, 75),
				GraphicsUnit.Pixel);

				bmp = crapped;
			}
			else {
				crapped = image;
			}

			return bmp;
		}

		/// <summary>
		/// Load a file from a file dialog
		/// </summary>
		/// <param name="FileDialog">Filedialog to use.</param>
		/// <returns>Filename of the loaded file.</returns>
		public string[] LoadImageFromDialog() {
			StringBuilder str = new StringBuilder();
			str.Append("All supported images|*.bmp;*.jpg;*.jpeg;*.gif;*.png;*.tif;*.tiff");
			str.Append("|Windows Bitmap (.bmp)|*.bmp");
			str.Append("|JPEG Files (.jpg/.jpeg)|*.jpg;*.jpeg");
			str.Append("|Portable Network Graphics (.png)|*.png");
			str.Append("|Compuserve GIF (.gif)|*.gif");
			str.Append("|Tagged Image File Format (.tif/.tiff)|*.tif;*.tiff");

			ofdAdd.FileName = "";
			ofdAdd.Multiselect = true;
			ofdAdd.Filter = str.ToString();

			if(ofdAdd.ShowDialog() == DialogResult.OK) {
				string Extension = System.IO.Path.GetExtension(ofdAdd.FileName).ToLower();
				if(Extension == ".bmp"
				|| Extension == ".jpg"
				|| Extension == ".jpeg"
				|| Extension == ".gif"
				|| Extension == ".png"
				|| Extension == ".tif"
				|| Extension == ".tiff")
					return ofdAdd.FileNames;
				else
					return null;
			}
			else
				return null;
		}

		// -----------------------------------------
		// PRIVATE PROPERTIES
		// -----------------------------------------

		private bool imageAbort() {
			return true;
		}

		private void lvMain_KeyUp(object sender, KeyEventArgs e) {
			MessageBox.Show(e.KeyValue.ToString());
		}
	}
}